<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator=">">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item :to="{ path: getPath }" v-if="getPath == '/roles'">角色列表</el-breadcrumb-item>
      <el-breadcrumb-item :to="{ path: getPath }" v-else>权限列表</el-breadcrumb-item>
    </el-breadcrumb>
    <el-card>
      <el-button type="primary" style="margin: 20px 0">添加角色</el-button>
      <!-- 表格 -->
      <el-table style="width: 100%" border :data="rolesList">
        <el-table-column type="expand">
          <template v-slot="{row}">
              <el-row :gutter="10" class="row" v-for="item in row.children" :key="item.id">
                <el-col :span="6">
                  <el-tag closable @close="deleteLevel3(row,item)">
                    {{item.authName}} 
                  </el-tag>
                  ▶
                </el-col>
                <el-col :span="18">
                  <el-row class="row" :gutter="10" v-for="level2 in item.children" :key="level2.id">
                    <el-col :span="8">
                      <el-tag closable type="success" @close="deleteLevel3(row,level2)">
                            {{level2.authName}}
                      </el-tag>
                      ▶
                    </el-col>
                    <el-col :span="16">
                      <el-tag style="margin:3px" closable type="warning"  v-for="level3 in level2.children" :key="level3.id" @close="deleteLevel3(row,level3)">
                            {{level3.authName}}
                      </el-tag>
                    </el-col>
                  </el-row>
                </el-col>
              </el-row>    
          </template>
        </el-table-column>
        <el-table-column label="#" type="index" align="center"> </el-table-column>
        <el-table-column label="角色名称" prop="roleName" width="220"> </el-table-column>
        <el-table-column label="角色描述" prop="roleDesc" width="220"> </el-table-column>
        <el-table-column label="操作" width="width"> 
            <template v-slot="{row}">
                <el-button type="primary" size="mini" icon="el-icon-eidt">编辑</el-button>
                <el-button type="danger" size="mini" icon="el-icon-delete" @click="deleteRole(row)">删除</el-button>
                <el-button type="warning" size="mini" icon="el-icon-star-off" @click="assignRoles(row)">分配权限</el-button>
            </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 分配权限的对话框 -->
    <el-dialog title="分配权限"  :visible.sync="dialogTableVisible" @close="cancel">
     <!-- 树形控件 -->
      <el-tree :data="assignTreeList" ref="tree" show-checkbox node-key="id" default-expand-all 
      :props="assignTreeProps" :default-checked-keys="defaultArray">
      </el-tree>
      <el-button @click="dialogTableVisible = false">取消</el-button>
      <el-button type="primary" @click="saveRoles">保存</el-button>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "roles",
  data(){
    return{
        // 储存权限数据
        rolesList:[],
        // 分配权限的对话框
        dialogTableVisible: false,
        // 储存树形数据
        assignTreeList:[],
        // 设置树形展示配置的数据
        assignTreeProps:{
          children: 'children',
          label: 'authName'
        },
        // 默认勾选
        defaultArray:[],
        // 收集当前角色的ID，供分配权限保存时发请求
        rolesID:''
    }
  },
  methods:{
    // 获取权限数据
    async getRolesList(){
        let {data:result} = await this.$API.get('roles')
        if(result.meta.status == 200){
            this.rolesList = result.data
        }
    },
    // 删除某一权限
    async deleteLevel3(row,level3,){
      this.$confirm('确定要删除?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(async () => {
          let {data:result} = await this.$API.delete(`roles/${row.id}/rights/${level3.id}`)
          if(result.meta.status == 200){
            // 重新给当前行赋值，从而更新数据
            row.children = result.data
            this.$message.success('删除成功')
          }else{
            this.$message.error('删除失败');
          }
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });
      
    },
    // 分配权限按钮
    async assignRoles(row){
      // 收集当前角色的ID
      this.rolesID = row.id
      let {data:result} = await this.$API.get('rights/tree')
      if(result.meta.status != 200){
        return this.$message,error('请求数据失败')
      }
      // 储存数据
      this.assignTreeList = result.data
      // 递归收集最后children的id，让属性默认勾选
      this.getTreeDefault(row,this.defaultArray)

      this.dialogTableVisible = true
    },
    // 递归收集最后一个children的ID
    getTreeDefault(node,arr){
      // 如果没有children属性，则跳出递归
      if(!node.children){
        return arr.push(node.id)
      }
      node.children.forEach(item => {
        return this.getTreeDefault(item,arr)
      })
    },
    // 关闭分配权限按钮弹出的对话框,关闭的回调
    cancel(){
       // 清空上次的id
      this.defaultArray = []
    },
    // 分配权限对话框的确定按钮的函数
    async saveRoles(){
      // 保存被勾选的id
      const keys = [
        ...this.$refs.tree.getHalfCheckedKeys(),
        ...this.$refs.tree.getCheckedKeys()
      ]
      const rids = keys.join(',')
      // 发起分配权限的请求
      let {data:result} = await this.$API.post(`roles/${this.rolesID}/rights`,{rids})
      if(result.meta.status != 200){
        return this.$message.error('分配权限失败')
      }
      // 刷新角色列表
      this.getRolesList()
      this.dialogTableVisible = false
    },
    // 删除角色按钮
     deleteRole(row){
       this.$confirm('确定要删除?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(async () => {
          let {data:result} = await this.$API.delete(`roles/${row.id}`)
          if(result.meta.status == 200){
            // 更新数据
            this.getRolesList()
            this.$message.success('删除成功')
          }else{
            this.$message.error('删除失败');
          }
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });
    }
  },
  mounted(){
    this.getRolesList()
  },
  computed:{
      // 给面包屑导航当前的路由
      getPath(){
        return this.$route.path 
      }
  }
};
</script>

<style scoped>
.row{
  border-bottom:1px solid rgb(146, 145, 145);
  padding: 10px;
  display: flex;
  align-items: center;
}
</style>